/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.zyj.hms.pushsample.slice;

import com.fasterxml.jackson.databind.JsonSerializable;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.zyj.hms.pushsample.ResourceTable;
import com.zyj.hms.pushsample.utils.Const;
import com.zyj.hms.pushsample.utils.LogUtil;
import com.zyj.hms.pushsample.utils.ThreadPoolUtil;
import com.zyj.hms.pushsample.utils.WakeUpUtils;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.IntentParams;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.window.dialog.ToastDialog;
import ohos.app.Context;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.bundle.IBundleManager;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import ohos.location.Locator;
import ohos.net.*;
import ohos.security.SystemPermission;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {
    private static final String TAG = MainAbilitySlice.class.getSimpleName();
    private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD000F00, TAG);
    private NetManager netManager;
    private Text notify2_reply;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        LogUtil.setText((Text) findComponentById(ResourceTable.Id_text_main));
        parseIntent(intent);
        Button button = (Button) findComponentById(ResourceTable.Id_token);
        Button internet = (Button) findComponentById(ResourceTable.Id_internet);
        Button location = (Button) findComponentById(ResourceTable.Id_location);
        Button flag_test = (Button) findComponentById(ResourceTable.Id_flag_test);
        notify2_reply = (Text) findComponentById(ResourceTable.Id_notify2_reply);
        if (button != null) {
            button.setClickedListener(this);
            internet.setClickedListener(this);
            location.setClickedListener(this);
            flag_test.setClickedListener(this);
        }
        wakeUpUtils = new WakeUpUtils();
        uiTaskDispatcher = getUITaskDispatcher();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        LogUtil.setText((Text) findComponentById(ResourceTable.Id_text_main));
    }

    public static void parseIntent(Intent intent) {
        if (intent == null) {
            return;
        }
        LogUtil.i("action is: " + intent.getAction() + ", bundle name is: " + intent.getBundle());

        IntentParams intentParams = intent.getParams();
        if (intentParams == null) {
            return;
        }
        for (String key : intentParams.keySet()) {
            Object obj = intentParams.getParam(key);
            if (obj instanceof byte[]) {
                LogUtil.i("key:" + key + ", value:" + new String((byte[]) obj, StandardCharsets.UTF_8));
            } else if (obj instanceof String) {
                LogUtil.i("key:" + key + ", value:" + obj);
            } else if (obj instanceof Integer) {
                LogUtil.i("key:" + key + ", Integer.value:" + obj);
            } else if (obj instanceof Boolean) {
                LogUtil.i("key:" + key + ", Boolean.value:" + obj);
            }
        }
    }

    private WakeUpUtils wakeUpUtils;
    private TaskDispatcher uiTaskDispatcher;


    @Override
    public void onClick(Component component) {
        int btnId = component.getId();
        switch (btnId) {
            case ResourceTable.Id_token:
                startTokenAbility();
                break;
            case ResourceTable.Id_internet:
                String url = "https://fc-mp-67dcfd0c-c143-49dd-81a6-3d6aabd6ef7b.next.bspapp.com/com-power";
                HashMap<String, Object> datas = new HashMap<>();
                datas.put("action", "sendHmsMsgBack");
                datas.put("pushId", "66001f71652341ed5e1f39b1");
                netRequest(url, datas);
                break;
            case ResourceTable.Id_location:
                accessLocation();
                break;
            case ResourceTable.Id_flag_test:
                //测试远程唤醒
                wakeUpUtils.wakeup(result ->
                        uiTaskDispatcher.asyncDispatch(() -> showTips(MainAbilitySlice.this, result)));
                break;
            default:
                LogUtil.i("nothing to do.");
                break;
        }
    }

    private void startTokenAbility() {
        Intent secondIntent = new Intent();
        Operation operation = new Intent.OperationBuilder()
                .withDeviceId("")
                .withBundleName("com.zyj.hms.pushsample")
                .withAbilityName("com.zyj.hms.pushsample.TokenAbility")
                .build();
        secondIntent.setOperation(operation);
        startAbility(secondIntent);
        LogUtil.i("Token page ability has created.");
    }

    private void accessInternet() {
        try {
            new Locator(this).getCachedLocation();
            showTips(this, "Location access succeeded.");
        } catch (SecurityException e) {
            requestPermission(SystemPermission.INTERNET, Const.PERM_INTERNET_REQ_CODE);
        }
    }

    private void accessLocation() {
        try {
            new Locator(this).getCachedLocation();
            showTips(this, "Location access succeeded.");
        } catch (SecurityException e) {
            requestPermission(SystemPermission.LOCATION, Const.PERM_LOCATION_REQ_CODE);
        }
    }

    private void requestPermission(String permission, int requestCode) {
        if (verifySelfPermission(permission) == IBundleManager.PERMISSION_GRANTED) {
            showTips(this, "Permission already obtained");
            return;
        }
        if (!canRequestPermission(permission)) {
            showTips(this, "Cannot request Permission");
            LogUtil.error(TAG, "Cannot request Permission");
            return;
        }
        requestPermissionsFromUser(new String[]{permission}, requestCode);
    }

    private void netRequest(String urlString, HashMap<String, Object> params) {
        netManager = NetManager.getInstance(null);
        if (!netManager.hasDefaultNet()) {
            return;
        }
        ThreadPoolUtil.submit(() -> {
            NetHandle netHandle = netManager.getDefaultNet();
            netManager.addDefaultNetStatusCallback(callback);
            HttpURLConnection connection = null;
            try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                URL url = new URL(urlString);
                URLConnection urlConnection = netHandle.openConnection(url, java.net.Proxy.NO_PROXY);
                if (urlConnection instanceof HttpURLConnection) {
                    connection = (HttpURLConnection) urlConnection;
                }
                connection.setDoOutput(true);
                connection.setRequestMethod("POST");
                connection.setRequestProperty("Content-Type", "application/json");
                connection.connect();

                // 创建ObjectMapper对象
                ObjectMapper mapper = new ObjectMapper();
                ObjectWriter writer = mapper.writer();
                String postData = writer.writeValueAsString(params);
//                String postData = "{\"action\":\"sendHmsMsgBack\",\"pushId\":\"65ffbff7213929f86649b7b7\"}";
                byte[] outputInBytes = postData.getBytes("UTF-8");

                // 发送请求数据
                try(OutputStream out = connection.getOutputStream()) {
                    out.write(outputInBytes);
                }

                try (InputStream inputStream = urlConnection.getInputStream()) {
                    byte[] cache = new byte[2 * 1024];
                    int len = inputStream.read(cache);
                    while (len != -1) {
                        outputStream.write(cache, 0, len);
                        len = inputStream.read(cache);
                    }
                } catch (IOException e) {
                    HiLog.error(LABEL_LOG, "%{public}s", "netRequest inner IOException");
                }
                String result = new String(outputStream.toByteArray());
                getUITaskDispatcher().asyncDispatch(() -> notify2_reply.setText(result));
                HttpResponseCache.getInstalled().flush();
            } catch (IOException e) {
                HiLog.error(LABEL_LOG, "%{public}s", "netRequest IOException");
            }
        });
    }

    private final NetStatusCallback callback = new NetStatusCallback() {
        @Override
        public void onAvailable(NetHandle handle) {
            HiLog.info(LABEL_LOG, "%{public}s", "NetStatusCallback onAvailable");
        }

        @Override
        public void onBlockedStatusChanged(NetHandle handle, boolean blocked) {
            HiLog.info(LABEL_LOG, "%{public}s", "NetStatusCallback onBlockedStatusChanged");
        }
    };

    private void showTips(Context context, String message) {
        new ToastDialog(context).setText(message).show();
    }

}
